<html>
<head><meta charset="utf-8"><title>obtain the type of a discriminant · general · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/index.html">general</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/obtain.20the.20type.20of.20a.20discriminant.html">obtain the type of a discriminant</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="204143545"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/obtain%20the%20type%20of%20a%20discriminant/near/204143545" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jason Hu <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/obtain.20the.20type.20of.20a.20discriminant.html#204143545">(Jul 16 2020 at 21:10)</a>:</h4>
<p>I am running into trouble of finding out the size of the discriminant of an enum type.</p>
<p>for</p>
<div class="codehilite"><pre><span></span><code>ty::Adt(def, subst)
</code></pre></div>


<p>I find that </p>
<div class="codehilite"><pre><span></span><code>def.repr.discr_type()
</code></pre></div>


<p>to find out the discriminant type. but the problem is this information does not reach to the end. when is this tag replaced by a smaller type? how should I reliably fetch the type of discriminant (potentially from layout)?</p>



<a name="204179445"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/obtain%20the%20type%20of%20a%20discriminant/near/204179445" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bjorn3 <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/obtain.20the.20type.20of.20a.20discriminant.html#204179445">(Jul 17 2020 at 07:53)</a>:</h4>
<p>There are multiple ways to encode the discriminant into memory. You can directly put the discriminant somewhere, or you can use the so called niche filling where invalid values of variant fields are used to encode that the enum is a different variant.</p>



<a name="204179591"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/obtain%20the%20type%20of%20a%20discriminant/near/204179591" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bjorn3 <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/obtain.20the.20type.20of.20a.20discriminant.html#204179591">(Jul 17 2020 at 07:55)</a>:</h4>
<p><a href="https://github.com/rust-lang/rust/blob/86c0b85da98a3c69e0fc9014e36e1c88bd3ae8d7/src/librustc_mir/interpret/place.rs#L1049">https://github.com/rust-lang/rust/blob/86c0b85da98a3c69e0fc9014e36e1c88bd3ae8d7/src/librustc_mir/interpret/place.rs#L1049</a></p>



<a name="204188907"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/obtain%20the%20type%20of%20a%20discriminant/near/204188907" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/obtain.20the.20type.20of.20a.20discriminant.html#204188907">(Jul 17 2020 at 09:55)</a>:</h4>
<p><span class="user-mention" data-user-id="320010">@Jason Hu</span> are you trying to figure out how a type is <em>represented</em>? "discriminant" is a high-level (type-checking) concept</p>



<a name="204188939"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/obtain%20the%20type%20of%20a%20discriminant/near/204188939" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/obtain.20the.20type.20of.20a.20discriminant.html#204188939">(Jul 17 2020 at 09:55)</a>:</h4>
<p><span class="user-mention" data-user-id="320010">@Jason Hu</span> like I was saying earlier, for any concrete representations you need to rely as much as possible on <code>Layout</code></p>



<a name="204188946"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/obtain%20the%20type%20of%20a%20discriminant/near/204188946" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/obtain.20the.20type.20of.20a.20discriminant.html#204188946">(Jul 17 2020 at 09:55)</a>:</h4>
<p>and assume the Rust types mean nothing (except for deciding some MIR semantics)</p>



<a name="204196211"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/obtain%20the%20type%20of%20a%20discriminant/near/204196211" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/obtain.20the.20type.20of.20a.20discriminant.html#204196211">(Jul 17 2020 at 11:43)</a>:</h4>
<p><span class="user-mention" data-user-id="320010">@Jason Hu</span> the following code might be an interesting read for you:<br>
<a href="https://github.com/rust-lang/rust/blob/c2dbebd3d4ad21e80ef4e7535dd1e868aaad7e50/src/librustc_mir/interpret/operand.rs#L607">https://github.com/rust-lang/rust/blob/c2dbebd3d4ad21e80ef4e7535dd1e868aaad7e50/src/librustc_mir/interpret/operand.rs#L607</a></p>



<a name="204196287"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/obtain%20the%20type%20of%20a%20discriminant/near/204196287" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/obtain.20the.20type.20of.20a.20discriminant.html#204196287">(Jul 17 2020 at 11:44)</a>:</h4>
<p>basically I think you dont want the size of the <em>discriminant</em>, you want the size of the <em>tag</em></p>



<a name="204196294"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/obtain%20the%20type%20of%20a%20discriminant/near/204196294" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/obtain.20the.20type.20of.20a.20discriminant.html#204196294">(Jul 17 2020 at 11:44)</a>:</h4>
<p>the tag is how the discriminant is represented in memory</p>



<a name="204196331"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/obtain%20the%20type%20of%20a%20discriminant/near/204196331" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/obtain.20the.20type.20of.20a.20discriminant.html#204196331">(Jul 17 2020 at 11:45)</a>:</h4>
<p>also see <a href="https://rustc-dev-guide.rust-lang.org/appendix/glossary.html#discriminant">https://rustc-dev-guide.rust-lang.org/appendix/glossary.html#discriminant</a></p>



<a name="204443588"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/obtain%20the%20type%20of%20a%20discriminant/near/204443588" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jason Hu <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/obtain.20the.20type.20of.20a.20discriminant.html#204443588">(Jul 20 2020 at 16:22)</a>:</h4>
<p>I am indeed trying to figure out how a type is implemented and am looking into TyAndLayout. but I am not able to just look at the layouts only as suggested by <span class="user-mention" data-user-id="119009">@eddyb</span> because I am somewhat trying to interpret semantic information carried by the types, which forces me to look into type first. <span class="user-mention" data-user-id="120791">@RalfJ</span> does lots of work on verifying rust code. I am wondering how do you guys handle code like <a href="https://doc.rust-lang.org/beta/src/core/ptr/mod.rs.html#264-269">https://doc.rust-lang.org/beta/src/core/ptr/mod.rs.html#264-269</a>?</p>



<a name="204443774"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/obtain%20the%20type%20of%20a%20discriminant/near/204443774" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/obtain.20the.20type.20of.20a.20discriminant.html#204443774">(Jul 20 2020 at 16:24)</a>:</h4>
<p><span class="user-mention" data-user-id="320010">@Jason Hu</span> it doesn't matter that that uses an union btw, it could just as well <code>memcpy</code> the bytes around</p>



<a name="204443815"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/obtain%20the%20type%20of%20a%20discriminant/near/204443815" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/obtain.20the.20type.20of.20a.20discriminant.html#204443815">(Jul 20 2020 at 16:25)</a>:</h4>
<p>the union just happens to be convenient</p>



<a name="204443903"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/obtain%20the%20type%20of%20a%20discriminant/near/204443903" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/obtain.20the.20type.20of.20a.20discriminant.html#204443903">(Jul 20 2020 at 16:25)</a>:</h4>
<p>the important thing is the data, <em>not</em> the Rust type (which mostly boils down to how you can access the data. at least in this case, there are more interesting semantics like valid values, and references in stacked borrows etc.)</p>



<a name="204444074"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/obtain%20the%20type%20of%20a%20discriminant/near/204444074" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/obtain.20the.20type.20of.20a.20discriminant.html#204444074">(Jul 20 2020 at 16:26)</a>:</h4>
<p>but generally, something like a <code>struct</code> is nothing more than a grouping of its components. <code>*mut [T]</code> is "just" like a <code>struct</code> with <code>*mut T</code> and <code>usize</code> fields that interacts with the typesystem better</p>



<a name="204444245"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/obtain%20the%20type%20of%20a%20discriminant/near/204444245" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/obtain.20the.20type.20of.20a.20discriminant.html#204444245">(Jul 20 2020 at 16:28)</a>:</h4>
<p>so really, all that <code>union</code> does is overlap the <code>*mut T</code> of <code>*mut [T]</code> with the <code>data</code> field and the <code>usize</code> of the <code>*mut [T]</code> with the <code>len</code> field</p>



<a name="204444369"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/obtain%20the%20type%20of%20a%20discriminant/near/204444369" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/obtain.20the.20type.20of.20a.20discriminant.html#204444369">(Jul 20 2020 at 16:29)</a>:</h4>
<p>it's more or less just a colocated "pointer and integer" pair, and the <code>T</code> in that example doesn't affect the semantics until you actually want to refer to elements</p>



<a name="204444503"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/obtain%20the%20type%20of%20a%20discriminant/near/204444503" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/obtain.20the.20type.20of.20a.20discriminant.html#204444503">(Jul 20 2020 at 16:30)</a>:</h4>
<p>it's possible the model you're trying to fit Rust in is overly simplistic and only happens to work for C code that does little to no type punning</p>



<a name="204444582"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/obtain%20the%20type%20of%20a%20discriminant/near/204444582" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/obtain.20the.20type.20of.20a.20discriminant.html#204444582">(Jul 20 2020 at 16:31)</a>:</h4>
<p>in general, you can have many views to the same memory, and you have to somehow account for them (even if maybe just some patterns and not all of them)</p>



<a name="204444733"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/obtain%20the%20type%20of%20a%20discriminant/near/204444733" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/obtain.20the.20type.20of.20a.20discriminant.html#204444733">(Jul 20 2020 at 16:32)</a>:</h4>
<p>I guess you can have a more in-depth discussion with <span class="user-mention" data-user-id="120791">@RalfJ</span> about how far a model checker can theoretically go on Rust code without manual proofs (which I believe is what RustBelt has - manual proofs, that is)</p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>